<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        function myTypeof(val) {
            var type = typeof(val);
            var toStr = Object.prototype.toString;
            var res = {
                '[object Array]' : 'array',
                '[object Object]' : 'object',
                '[object Number]' : 'number',
                '[object Boolean]' : 'boolean',
                '[object String]' : 'string',
            }
            // 判断是否为null，是则返回字符串类型null，原因是因为历史遗留bug，typeof（null）判断为object所以要进行区分
            if(val === null) {
                return 'null';
            }else if(type === 'object') {        // 判断是否为引用类型，是则使用使用toString通过改变this进一步判断数据类型
                var ret = toStr.call(val);       // 将输出值先进行缓存，然后对比输出
                return res[ret];
            }else {                              // 都不是则直接通过typeof输出
                return type;
            }
        }
        // 基本数据类型
        console.log(myTypeof(123));         // number
        console.log(myTypeof('123'));       // string
        console.log(myTypeof(true));        // boolean
        console.log(myTypeof(null));        // null
        console.log(myTypeof(undefined));   // undefined
        console.log(myTypeof(Symbol()));    // symbol
        // 引用数据类型
        console.log(myTypeof(function(){}));// function
        console.log(myTypeof({}));          // object
        console.log(myTypeof([]));          // array
        console.log(myTypeof(new String()));// string
        console.log(myTypeof(new Number()));// number
        console.log(myTypeof(new Boolean()));   // boolean
    </script>
</body>
</html>